﻿using System;
using System.Data;
using System.Data.SqlClient;
using DataAccess;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DataAccessTest
{


    /// <summary>
    ///Se trata de una clase de prueba para AppDatabaseTest y se pretende que
    ///contenga todas las pruebas unitarias AppDatabaseTest.
    ///</summary>
    [TestClass()]
    public class AppDatabaseTest
    {

        #region Test Context
        private TestContext testContextInstance;

        /// <summary>
        ///Obtiene o establece el contexto de la prueba que proporciona
        ///la información y funcionalidad para la ejecución de pruebas actual.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Atributos de prueba adicionales
        // 
        //Puede utilizar los siguientes atributos adicionales mientras escribe sus pruebas:
        //
        //Use ClassInitialize para ejecutar código antes de ejecutar la primera prueba en la clase 
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup para ejecutar código después de haber ejecutado todas las pruebas en una clase
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize para ejecutar código antes de ejecutar cada prueba
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup para ejecutar código después de que se hayan ejecutado todas las pruebas
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion
        #endregion

        #region SQL
        /// <summary>
        ///Una prueba de GetCustomers
        ///</summary>
        [TestMethod()]
        public void GetCustomersTest()
        {
            AppDatabase db = new AppDatabase();
            //GetCustomersLike(string.Empty, 91);
            GetCustomersLike("A", 4);
            GetCustomersLike("B", 7);
            GetCustomersLike("X", 0);
        }


        private void GetCustomersLike(string CompanyName, int ExpectedRows)
        {
            AppDatabase db = new AppDatabase();
            DataSet ds = db.GetCustomers(CompanyName);
            Assert.AreEqual<int>(1, ds.Tables.Count);
            Assert.AreEqual<int>(ExpectedRows, ds.Tables[0].Rows.Count);
            TestContext.WriteLine("---- EMPLOYEES ----");
            TestContext.WriteLine(string.Format("CompanyName: '{0}'", CompanyName));
            TestContext.WriteLine(ds.GetXml());
        }
        #endregion

        #region SP
        /// <summary>
        ///Una prueba de GetCustomers
        ///</summary>
        [TestMethod()]
        public void CustomersGet_SP()
        {
            AppDatabase db = new AppDatabase();
            //GetCustomersLike(string.Empty, 91);
            CustomersGet_SPLike("A", 4);
            CustomersGet_SPLike("B", 7);
            CustomersGet_SPLike("X", 0);
        }


        private void CustomersGet_SPLike(string CompanyName, int ExpectedRows)
        {
            AppDatabase db = new AppDatabase();
            DataSet ds = db.CustomersGet_SP(CompanyName);
            Assert.AreEqual<int>(1, ds.Tables.Count);
            Assert.AreEqual<int>(ExpectedRows, ds.Tables[0].Rows.Count);
            TestContext.WriteLine("---- EMPLOYEES ----");
            TestContext.WriteLine(string.Format("CompanyName: '{0}'", CompanyName));
            TestContext.WriteLine(ds.GetXml());
        }
        #endregion

        #region Test Connection
        public void TestConnectionTest()
        {
            AppDatabase db = new AppDatabase();
            db.TestConnection();
        }
        #endregion

        #region Transaction
        [TestMethod]
        public void InsertarCategoriaProductoTest()
        {
            string CategoryName = GetNextCategoryName();
            string ProductName = GetNextProductName();
            // cuenta registros antes
            int initialCategoryCount = GetCount("Categories");
            int initialProductsCount = GetCount("Products");
            // inserta
            AppDatabase db = new AppDatabase();
            db.InsertarCategoriaProducto(CategoryName, ProductName);
            // cuenta registros despues
            int actualCategoryCount = GetCount("Categories");
            int actualProductsCount = GetCount("Products");
            // verifica
            Assert.AreEqual<int>(initialCategoryCount + 1, actualCategoryCount);
            Assert.AreEqual<int>(initialProductsCount + 1, actualProductsCount);
        }

        #region Private SQL
        private int GetCount(string TableName)
        {
            string SqlText = "SELECT COUNT(*) FROM " + TableName;
            return Convert.ToInt32(ExecuteScalar(SqlText));
        }

        private string GetNextCategoryName()
        {
            string SqlText =
               "SELECT ISNULL(MAX(CategoryID), 0) FROM Categories";
            int ID = Convert.ToInt32(ExecuteScalar(SqlText));
            return string.Format("Categoria {0}", ID + 1);
        }
        private string GetNextProductName()
        {
            string SqlText =
               "SELECT ISNULL(MAX(ProductID), 0) FROM Products";
            int ID = Convert.ToInt32(ExecuteScalar(SqlText));
            return string.Format("Producto {0}", ID + 1);
        }
        #endregion

        #endregion

        #region Helpers
        protected object ExecuteScalar(string SqlText)
        {
            // crea conexion
            using (SqlConnection cn = new SqlConnection(AppDatabase.ConnectionString))
            {
                cn.Open();      // abre conexion
                SqlCommand cmd = new SqlCommand(SqlText, cn);
                return cmd.ExecuteScalar(); // ejecuto
            }
        }
        #endregion

    }
}
